package com.loong.data.handler;

import com.alibaba.fastjson.JSON;
import com.loong.common.rabbitmq.dto.GoodsBaseDTO;
import com.loong.common.rabbitmq.dto.GoodsBrandDTO;
import com.loong.common.utils.TransformUtils;
import com.loong.data.common.backend.param.GoodsBrandParam;
import com.loong.data.common.backend.param.PageParam;
import com.loong.data.common.backend.result.GoodsBrandResult;
import com.loong.data.common.forehead.param.GoodsBrandAndPageForeheadParam;
import com.loong.data.common.forehead.param.GoodsBrandForeheadParam;
import com.loong.data.common.forehead.param.PageForeheadParam;
import com.loong.data.common.forehead.result.GoodsBrandForeheadResult;
import com.loong.data.model.GoodsBrandModel;
import com.loong.data.model.GoodsModel;
import com.loong.data.repository.GoodsBrandRepository;
import com.loong.data.utils.ESPageUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description: 处理有关商品品牌业务的handler
 * @Author: LiuQun
 * @Date: 2020/12/5 15:39
 */
@Component
public class GoodsBrandHandler {

    @Resource
    private GoodsBrandRepository brandRepository;

    @Resource
    private RestHighLevelClient client;

    @Resource
    private ElasticsearchRestTemplate template;

    /**
     * 新增商品品牌到ES中：MQ消费者中调用该方法
     * @param goodsBrandDTO 商品品牌
     */
    public void saveGoodsBrand(GoodsBrandDTO goodsBrandDTO){
        brandRepository.save(TransformUtils.transform(goodsBrandDTO, GoodsBrandModel.class));
    }

    /**
     * 更新商品品牌到ES中：MQ消费者中调用该方法
     * @param goodsBrandDTO 商品品牌
     */
    public void updateGoodsBrand(GoodsBrandDTO goodsBrandDTO){
        UpdateRequest updateRequest = new UpdateRequest("goods_brand", goodsBrandDTO.getId().toString());
        updateRequest.doc(JSON.toJSONString(goodsBrandDTO), XContentType.JSON);
        try {
            client.update(updateRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据品牌id删除ES中的商品品牌：MQ消费者中调用该方法
     * @param brandId 商品品牌id
     */
    public void deleteGoodsBrandById(Long brandId){
        if (ObjectUtils.isEmpty(brandId)) return;
        brandRepository.deleteById(brandId);
    }

    /**
     * 后台根据参数查询商品品牌
     * @param brandParam 品牌查询
     * @param pageParam 分页参数
     * @return 商品品牌集合
     */
    public List<GoodsBrandResult> findGoodsBrandByParam(GoodsBrandParam brandParam, PageParam pageParam){
        //参数转换
        GoodsBrandForeheadParam foreheadBrandParam = null;
        PageForeheadParam foreheadPageParam = null;
        if (ObjectUtils.isNotEmpty(brandParam)){
            foreheadBrandParam = TransformUtils.transform(brandParam,GoodsBrandForeheadParam.class);
        }
        if (ObjectUtils.isNotEmpty(pageParam)){
            foreheadPageParam = TransformUtils.transform(pageParam,PageForeheadParam.class);
        }
        //获得查询的商品品牌集合
        List<GoodsBrandForeheadResult> foreheadResultList = this.commonFindGoodsBrandByParam(foreheadBrandParam, foreheadPageParam);
        if (CollectionUtils.isEmpty(foreheadResultList)) return null;
        return TransformUtils.transformList(foreheadResultList,GoodsBrandResult.class);
    }

    /**
     * 前台根据参数查询商品品牌
     * @param param 查询参数
     * @return 商品品牌集合
     */
    public List<GoodsBrandForeheadResult> foreheadFindGoodsBrandByParam(GoodsBrandAndPageForeheadParam param){
        GoodsBrandForeheadParam brandParam = null;
        PageForeheadParam pageParam = null;
        if (ObjectUtils.isNotEmpty(param)){
            brandParam = param.getGoodsBrandParam();
            pageParam = param.getPageParam();
        }
        return this.commonFindGoodsBrandByParam(brandParam,pageParam);
    }

    /**
     * 公共的方法：根据参数查询商品品牌
     * @param brandParam 商品品牌参数
     * @param pageParam 分页参数
     * @return 商品品牌集合
     */
    private List<GoodsBrandForeheadResult> commonFindGoodsBrandByParam(GoodsBrandForeheadParam brandParam, PageForeheadParam pageParam){
        //构建布尔查询
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        if (ObjectUtils.isNotEmpty(brandParam)){
            if (ObjectUtils.isNotEmpty(brandParam.getCategoryId())){
                //根据分类id查询
                boolQuery.must(QueryBuilders.termQuery("categoryId",brandParam.getCategoryId()));
            }
            if (ObjectUtils.isNotEmpty(brandParam.getGoodsBrandName())){
                //根据品牌名称查询
                boolQuery.must(QueryBuilders.matchPhraseQuery("brandName",brandParam.getGoodsBrandName()));
            }
        }else {
            boolQuery.must(QueryBuilders.matchAllQuery());
        }
        Pageable pageable = ESPageUtil.getPageableByParam(pageParam);
        return executeQuery(boolQuery,pageable);
    }

    /**
     * 执行查询请求，并获得结果
     * @param queryBuilder 查询条件
     * @param pageable 分页
     * @return 商品集合
     */
    private List<GoodsBrandForeheadResult> executeQuery(QueryBuilder queryBuilder, Pageable pageable){
        //存放商品信息的集合
        List<GoodsBrandModel> modelList = new ArrayList<>();
        //构建查询条件
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(queryBuilder)
                .withPageable(pageable)
                .build();
        //获得查询的结果
        SearchHits<GoodsBrandModel> hits = template.search(searchQuery, GoodsBrandModel.class);
        List<SearchHit<GoodsBrandModel>> hitList = hits.getSearchHits();
        for (SearchHit<GoodsBrandModel> hit : hitList) {
            GoodsBrandModel model = hit.getContent();
            modelList.add(model);
        }
        return TransformUtils.transformList(modelList,GoodsBrandForeheadResult.class);
    }



}
